"""
@Author: Bright
@File: agent_react.py
@Time: 2025/10/15
@Desc: 规划 + 工具调用 + 反思
"""
import os

from dotenv import load_dotenv
from langchain.agents import AgentExecutor, create_react_agent
from langchain_core.prompts import PromptTemplate
from langchain_core.tools import Tool
from langchain_openai import AzureChatOpenAI


# 1. 定义工具 - Agent的"手脚"
def search_tool(query: str) -> str:
    """模拟搜索工具"""
    print(f"[工具调用] 搜索: {query}")
    # 模拟返回结果
    return f"关于'{query}'的搜索结果：LangGraph是一个用于构建状态ful、多Actor应用的框架。2021年发布。\n"


def calculator_tool(expression: str) -> str:
    """计算器工具"""
    print(f"[工具调用] 计算: {expression}")
    try:
        result = eval(expression)  # 实际应用中请使用更安全的评估方式
        return f"计算结果: {result}\n"
    except Exception as e:
        return f"计算错误: {e}"


# 创建工具列表
tools = [
    Tool(
        name="Search",
        func=search_tool,
        description="用于搜索最新信息和知识"
    ),
    Tool(
        name="Calculator",
        func=calculator_tool,
        description="用于执行数学计算"
    )
]

# 2. 初始化LLM
# llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
load_dotenv()

llm = AzureChatOpenAI(
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),
    azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
    azure_deployment=os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME"),
    api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
    temperature=0.7
)

# 3. 创建带有反思机制的ReAct Agent
template = """Answer the following questions as best you can. You have access to the following tools:

{tools}

Use the following format:

Question: the input question you must answer
Thought: you should always think about what to do. Be efficient and avoid unnecessary steps.
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question

Important: Always include Reflection after each Observation to evaluate your progress.

Begin!

Question: {input}
Thought:{agent_scratchpad}"""

prompt = PromptTemplate.from_template(template)
# 创建Agent
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True)


# 4. 测试 - 这个任务需要规划、工具调用和反思
def run_enhanced_agent():
    result = agent_executor.invoke({
        "input": "请搜索LangGraph的最新信息，然后计算它的发布年份加上5年是多少年？"
    })
    return result


# 运行Demo
if __name__ == "__main__":
    print("=== 增强型ReAct Agent Demo ===")
    result = run_enhanced_agent()
    print(result)
